// Kony


#include "Player/BasePlayerState.h"

#include "AbilitySystem/BaseAbilitySystemComponent.h"
#include "AbilitySystem/BaseAttributeSet.h"
#include "AbilitySystem/Data/LevelConfig.h"
#include "Interaction/CombatInterface.h"
#include "Net/UnrealNetwork.h"

//基础玩家属性类
ABasePlayerState::ABasePlayerState()
{
	//设置AbilitySystemComponent 赋予 BaseAbilitySystemComponent
	AbilitySystemComponent = CreateDefaultSubobject<UBaseAbilitySystemComponent>("AbilitySystemComponent");
	//设置可复制 用于多人服务器复制数据
	AbilitySystemComponent->SetIsReplicated(true);
	//这是玩家复制模式设置成Mixed 混合复制模式， 还有其他3种 Full Mixed Minimal 
	AbilitySystemComponent->SetReplicationMode(EGameplayEffectReplicationMode::Mixed);
	//设置AttributeSet属性集 赋予 BaseAttributeSet
	AttributeSet = CreateDefaultSubobject<UBaseAttributeSet>("AttributeSet");
	
	NetUpdateFrequency = 100.f;//网络更新频率
	//设置修为计算公式
	CultivationConfigs = {
		{ TEXT("凡人"), 1, 10 },
		{ TEXT("练气"), 13, 10 },
		{ TEXT("筑基"), 9, 10 },
		{ TEXT("金丹"), 9, 10 },
		{ TEXT("元婴"), 9, 10 }
	};

	if (LevelConfigDataTable)
	{
		// 初始化升级所需经验值缓存
		if (XPRequiredForNextLevel == 0)
		{
			XPRequiredForNextLevel = ULevelConfig::GetXPRequiredForCurrentLevel(LevelConfigDataTable, Level);
		}
	}
}

void ABasePlayerState::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	//设置Level属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, Level);
	//设置XP属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, XP);
	//设置LingQi属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, LingQi);
	//设置Cultivation属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, Cultivation);
	//设置CultivationTier属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, CultivationTier);
	//设置CultivationStage属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, CultivationStage);
	//设置XPRequiredForNextLevel属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, XPRequiredForNextLevel);
	//设置AttributePoints属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, AttributePoints);
	//设置SpellPoints属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, SpellPoints);
	//设置SelectedTarget属性 用于多人服务器复制数据
	DOREPLIFETIME(ABasePlayerState, SelectedTarget);
}

UAbilitySystemComponent* ABasePlayerState::GetAbilitySystemComponent() const
{
	return AbilitySystemComponent;
}

void ABasePlayerState::SetXPRequiredForNextLevel(int32 InXPRequired)
{
	XPRequiredForNextLevel = InXPRequired;
}

void ABasePlayerState::AddToLevel(int32 InLevel)
{
	Level += InLevel;
	SetXP(0);//升级后 经验设置为0
	OnLevelChangedDelegate.Broadcast(Level,true);
	UpdateCultivationFromLevel();
	OnCultivationChangedDelegate.Broadcast(Cultivation, CultivationTier, CultivationStage);
	
	// 等级变化时更新升级所需经验值缓存
	if (LevelConfigDataTable)
	{
		int32 NextLevelXP = ULevelConfig::GetXPRequiredForCurrentLevel(LevelConfigDataTable, Level);
		SetXPRequiredForNextLevel(NextLevelXP);
	}
}

void ABasePlayerState::SetLevel(int32 InLevel, bool bLevelUp)
{
	Level = InLevel;
	OnLevelChangedDelegate.Broadcast(Level, bLevelUp);
	UpdateCultivationFromLevel();
	OnCultivationChangedDelegate.Broadcast(Cultivation, CultivationTier, CultivationStage);
	
	// 等级变化时更新升级所需经验值缓存
	if (LevelConfigDataTable)
	{
		int32 NextLevelXP = ULevelConfig::GetXPRequiredForCurrentLevel(LevelConfigDataTable, Level);
		SetXPRequiredForNextLevel(NextLevelXP);
	}
}

//添加经验值（修为值）
void ABasePlayerState::AddToXP(int32 InXP)
{
	XP += InXP;
	OnXPChangedDelegate.Broadcast(XP);
}
//设置经验值（修为值）
void ABasePlayerState::SetXP(int32 InXP)
{
	XP = InXP;
	OnXPChangedDelegate.Broadcast(XP);
}
//添加灵气
void ABasePlayerState::AddToLingQi(int32 InLingQi)
{
	LingQi += InLingQi;
	OnLingQiChangedDelegate.Broadcast(LingQi);
}
//设置灵气
void ABasePlayerState::SetLingQi(int32 InLingQi)
{
	LingQi = InLingQi;
	OnLingQiChangedDelegate.Broadcast(LingQi);
}
//设置属性点
void ABasePlayerState::SetAttributePoints(int32 InAttributePoints)
{
	AttributePoints = InAttributePoints;
	OnAttributePointsChangedDelegate.Broadcast(AttributePoints);
}
//设置技能点
void ABasePlayerState::SetSpellPoints(int32 InSpellPoints)
{
	SpellPoints = InSpellPoints;
	OnSpellPointsChangedDelegate.Broadcast(SpellPoints);
}

void ABasePlayerState::AddToCultivation(int32 InCultivation)
{
	Cultivation = InCultivation;
	OnCultivationChangedDelegate.Broadcast(Cultivation, CultivationTier, CultivationStage);
}

void ABasePlayerState::AddToCultivationTier(int32 InCultivationTier)
{
	CultivationTier = InCultivationTier;
	OnCultivationChangedDelegate.Broadcast(Cultivation, CultivationTier, CultivationStage);
}

void ABasePlayerState::AddToCultivationStage(int32 InCultivationStage)
{
	CultivationStage = InCultivationStage;
	OnCultivationChangedDelegate.Broadcast(Cultivation, CultivationTier, CultivationStage);
}

void ABasePlayerState::AddToAttributePoints(int32 InAttributePoints)
{
	AttributePoints += InAttributePoints;
	OnAttributePointsChangedDelegate.Broadcast(AttributePoints);
}

void ABasePlayerState::AddToSpellPoints(int32 InSpellPoints)
{
	SpellPoints += InSpellPoints;
	OnSpellPointsChangedDelegate.Broadcast(SpellPoints);
}

void ABasePlayerState::SetSelectedTarget(AActor* InSelectedTarget)
{
	AActor* OldTarget = SelectedTarget;
	SelectedTarget = InSelectedTarget;
	
	//隐藏旧目标指示器
	if (OldTarget && OldTarget->Implements<UCombatInterface>())
	{
		ICombatInterface::Execute_HideTargetIndicator(OldTarget);
	}
	//显示新目标指示器
	if (SelectedTarget && SelectedTarget->Implements<UCombatInterface>())
	{
		ICombatInterface::Execute_ShowTargetIndicator(SelectedTarget);
	}
	
	//广播委托
	OnSelectedTargetChangedDelegate.Broadcast(SelectedTarget, OldTarget);
}

//通过总等级计算修为大境界、层数小境界、境界阶数
void ABasePlayerState::UpdateCultivationFromLevel()
{
	int32 RemainingLevel = Level;
    
	for (int32 i = 0; i < CultivationConfigs.Num(); ++i)
	{
		const FCultivationStageConfig& Config = CultivationConfigs[i];
		int32 LevelsInThisCultivation = Config.Tiers * Config.StagesPerTier;

		if (RemainingLevel <= LevelsInThisCultivation)
		{
			Cultivation = i; // 当前大境界 ID
			CultivationTier = (RemainingLevel - 1) / Config.StagesPerTier + 1;
			CultivationStage = (RemainingLevel - 1) % Config.StagesPerTier + 1;
			return;
		}

		RemainingLevel -= LevelsInThisCultivation;
	}

	// 超出最大配置，默认最后一层满级
	if (CultivationConfigs.Num() > 0)
	{
		const FCultivationStageConfig& LastConfig = CultivationConfigs.Last();
		Cultivation = CultivationConfigs.Num() - 1;
		CultivationTier = LastConfig.Tiers;
		CultivationStage = LastConfig.StagesPerTier;
	}
}

void ABasePlayerState::OnRep_Level(int32 OldLevel)
{
	//在客户端广播等级值变更广播
	OnLevelChangedDelegate.Broadcast(Level, true);
	UpdateCultivationFromLevel();
}

void ABasePlayerState::OnRep_XP(int32 OldXP)
{
	//在客户端广播修为值变更广播
	OnXPChangedDelegate.Broadcast(XP);
}

void ABasePlayerState::OnRep_LingQi(int32 OldLingQi)
{
	//在客户端广播灵气值变更广播
	OnLingQiChangedDelegate.Broadcast(LingQi);
}


void ABasePlayerState::OnRep_Cultivation(int32 OldCultivation)
{
	OnCultivationChangedDelegate.Broadcast(Cultivation, CultivationTier, CultivationStage);
}

void ABasePlayerState::OnRep_CultivationTier(int32 OldCultivationTier)
{
	OnCultivationChangedDelegate.Broadcast(Cultivation, CultivationTier, CultivationStage);
}

void ABasePlayerState::OnRep_CultivationStage(int32 OldCultivationStage)
{
	OnCultivationChangedDelegate.Broadcast(Cultivation, CultivationTier, CultivationStage);
}
//当前等级升级所需经验
void ABasePlayerState::OnRep_XPRequiredForNextLevel(int32 OldXPRequired)
{
	// 修复：广播复制后的最新值，而不是旧值
	OnXPRequiredForNextLevelDelegate.Broadcast(XPRequiredForNextLevel);
}

void ABasePlayerState::OnRep_AttributePoints(int32 OldAttributePoints)
{
	// 修复：广播复制后的最新值，而不是旧值
	OnAttributePointsChangedDelegate.Broadcast(AttributePoints);
}

void ABasePlayerState::OnRep_SpellPoints(int32 OldSpellPoints)
{
	// 修复：广播复制后的最新值，而不是旧值
	OnSpellPointsChangedDelegate.Broadcast(SpellPoints);
}


void ABasePlayerState::OnRep_SelectedTarget(AActor* OldSelectedTarget)
{
	//隐藏旧目标指示器
	if (OldSelectedTarget && OldSelectedTarget->Implements<UCombatInterface>())
	{
		ICombatInterface::Execute_HideTargetIndicator(OldSelectedTarget);
	}
	//显示新目标指示器
	if (SelectedTarget && SelectedTarget->Implements<UCombatInterface>())
	{
		ICombatInterface::Execute_ShowTargetIndicator(SelectedTarget);
	}
	//选中目标变化时广播委托
	OnSelectedTargetChangedDelegate.Broadcast(SelectedTarget, OldSelectedTarget);
}
